package com.myprocessing.box;

import java.util.Arrays;
import java.util.Comparator;
import java.util.Map;
import java.util.SortedSet;

import processing.core.PConstants;

import com.myprocessing.gui.util.Color;

/*
 * 	usage example:
 * 		
  		PieChart p = (PieChart)uiCtx.getBean("testPieChart");
		p.setValueForGroup("red", 19);
		p.setColorForGroup("red", new Color(75f, 25f, 25f));
		p.setValueForGroup("blimp", 24);
		p.setColorForGroup("blimp", new Color(25f, 75f, 25f));
		p.removeGroup("blimp");
 *
 */

public class PieChart extends Box {

	protected Map<Object,Double> groups;
	protected Map<Object,Color> groupColors;
	protected float radius;
	protected Object[] sortedKeys;
	
	// call this at the end of any method that modifies the groups map
	private void sortKeys() {
		sortedKeys = groups.keySet().toArray();
		Arrays.sort(sortedKeys, new SortKeyByValue());
	}
	
	class SortKeyByValue implements Comparator<Object> {
		public int compare(Object o1, Object o2) {
			return (int)(groups.get(o1).doubleValue() - groups.get(o2).doubleValue());
		}
	}
	
	public void removeGroup(Object key) {
		groups.remove(key);
		groupColors.remove(key);
		sortKeys();
	}
	
	public void setValueForGroup(Object key, double val) {		
		if (!groupColors.containsKey(key)) {
			groupColors.put(key, new Color(100f, 100f, 100f));
		}
		groups.put(key, new Double(val));
		sortKeys();
	}
	
	public double getValueForGroup(Object key) {
		return groups.get(key).doubleValue();
	}
	
	public void setColorForGroup(Object key, Color c) {
		if (!groups.containsKey(key)) {
			groups.put(key, new Double(0));
		}
		groupColors.put(key, c);
		sortKeys();
	}
	
	public Color getColorForGroup(Object key) {
		return groupColors.get(key);
	}
	
	public void drawBox() {
		double total = 0;
		for (Double d : groups.values()) {
			total += d.doubleValue();
		}
		pApplet.pushMatrix();
		pApplet.translate(position.getX(), position.getY());
		pApplet.noStroke();
		
		double totalTheta = 0;
		for (Object key : sortedKeys) {
			double theta = (groups.get(key) / total) * PConstants.TWO_PI;
			Color c = groupColors.get(key);
			pApplet.fill(c.getRed(), c.getGreen(), c.getBlue());
			pApplet.arc(0, 0, radius*2, radius*2, (float)totalTheta, (float)(totalTheta + theta));
			totalTheta += theta;
		}
		pApplet.strokeWeight(1);
		pApplet.noFill();
		pApplet.stroke(0);
		pApplet.ellipse(0, 0, radius*2, radius*2);
		pApplet.popMatrix();
	}

	public Map<Object, Double> getGroups() {
		return groups;
	}

	public void setGroups(Map<Object, Double> groups) {
		this.groups = groups;
		sortKeys();
	}

	public Map<Object, Color> getGroupColors() {
		return groupColors;
	}

	public void setGroupColors(Map<Object, Color> groupColors) {
		this.groupColors = groupColors;
	}

	public float getRadius() {
		return radius;
	}

	public void setRadius(float radius) {
		this.radius = radius;
	}
	
}
